﻿using System;
using System.Collections.Generic;
using BulletSharp;
using ET.HelloWorld.Hotfix.Entitys;
using ETHotfix;
using ETModel;
using PF;
using UnityEngine;

namespace ET.HelloWorld.Hotfix.Handlers {
    [MessageHandler(AppType.Map)]
    public class G2M_EnterMapHandler : AMRpcHandler<G2M_EnterMap, M2G_EnterMap> {
        protected override void Run(Session session, G2M_EnterMap message, Action<M2G_EnterMap> reply) {
            //抽象方法是同步的,需要操作异步代码,从这里转一手
            RunAsync(session, message, reply).Coroutine();
        }

        protected async ETVoid RunAsync(Session session, G2M_EnterMap message, Action<M2G_EnterMap> reply) {
            //回复
            M2G_EnterMap response = new M2G_EnterMap();
            M2C_PlayerEnterMap playerEnterMsg = new M2C_PlayerEnterMap();

            var mapUnitsComp = Game.Scene.GetComponent<UnitsComponent>();
            var cfgComp = Game.Scene.GetComponent<ConfigComponent>();

            try {
                //!!! 玩家成功连接到Map服务器,必须调用本方法初始化!
                var mapPlayer = await session.MapPlayerLoginSuccess(message.GateSessionInstanceId, null);

                //创建一个单位,客户端相机依附在这个单位上
                //让客户端可以游览,并在自定义位置发出方块(未完成)
                var pos = new Vector3(-10, 10, -10);
                var unitCfg = Game.Scene.GetComponent<ConfigComponent>().Get<UnitConfig>(1003);
                GameUnit unit = ComponentFactory.CreateWithId<GameUnit, long>(IdGenerater.GenerateId(), mapPlayer.Id);
                unit.UnitConfigId = unitCfg.Id;
                unit.AddComponent<MoveComponent>();
                unit.SetPosition(pos);
                var unitInfo = unit.BuildUnitInfo();
                //加入到当前玩家的单位管理中
                mapPlayer.AddSelfUnit(unit);
                //通知其他客户端
                playerEnterMsg.NewUnits.Add(unitInfo);
                //加入客户端调试线框
                Game.Scene.GetComponent<DebugInfoSyncComponent>()?.UpdateGizmosMeshSync(unit.Id, unitInfo);


                //创建一个测试方块,自由落体
                var unit1Cfg = cfgComp.Get<UnitConfig>(1001);
                var pos1 = pos + Vector3.up * 20 + Vector3.forward * 1;
                var unit1Mass = 0.1f;
                GameUnit unit1 = ComponentFactory.CreateWithId<GameUnit, long>(IdGenerater.GenerateId(), mapPlayer.Id);
                unit1.UnitConfigId = unit1Cfg.Id;
                unit1.SetScale(unit1Cfg.GetLocalScale());
                unit1.Center = unit1Cfg.GetCenter();
                unit1.SetPosition(pos1);
                //加入物理引擎
                unit1.AddComponent<BulletCollisionShape, CollisionShape>(unit1Cfg.CreateBulletCollisionShape());
                unit1.AddComponent<BulletCollisionObject, float, Vector3, Quaternion>(unit1Mass, unit1.GetPosition(), unit1.GetRotation());
                var unitInfo1 = unit1.BuildUnitInfo();
                //加入到当前玩家的单位管理中
                mapPlayer.AddSelfUnit(unit1);
                //通知其他客户端
                playerEnterMsg.NewUnits.Add(unit1.BuildUnitInfo());
                //加入客户端调试线框
                Game.Scene.GetComponent<DebugInfoSyncComponent>()?.UpdateGizmosMeshSync(unit1.Id, unitInfo1);



                //回复当前客户端
                response.MapPlayerInstanceId = mapPlayer.InstanceId;
                var units = mapUnitsComp.GetAll();
                foreach (var u in units) {
                    response.Units.Add((u as GameUnit).BuildUnitInfo());
                }
                response.SelfUnitIds.Add(unit.Id);
                //加入调试信息
                response.AllGizmosMeshs.Add(Game.Scene.GetComponent<DebugInfoSyncComponent>().GetAllGizmosMesh());
                response.AllRayTestLine.Add(Game.Scene.GetComponent<DebugInfoSyncComponent>().GetAllGizmosRayTestLine());
                reply(response);

                //MessageHelper.Broadcast(playerEnterMsg, mapPlayer.Id);
                playerEnterMsg.MapBroadcastAllPlayers(mapPlayer.Id);

            } catch (Exception e) {
                ReplyError(response, e, reply);
            }
        }
    }
}